home *** CD-ROM | disk | FTP | other *** search
- /*********************************
- * *
- * Visual Shell v1.17 10/92 *
- * *
- * by Torsten Jürgeleit *
- * *
- * vsh main part *
- * *
- *********************************/
-
- /* Includes */
-
- #include "includes.h"
-
- /* Defines */
-
- #define MAX_ARGUMENTS 4
-
- #define ARGUMENT_LEFT 0
- #define ARGUMENT_RIGHT 1
- #define ARGUMENT_HIDE 2
- #define ARGUMENT_REMOVE 3
-
- #define CTOB(cptr) ((BPTR)((ULONG)cptr >> 2)) /* Convert C ptr to BCPL ptr */
- #define BTOC(bptr) ((VOID *)((ULONG)bptr << 2)) /* Convert BCPL ptr to C ptr */
-
- #define MIN_VSH_WIDTH (USHORT)640 /* NTSC resolution */
- #define MIN_VSH_HEIGHT (USHORT)200
-
- #define VSH_PROCESS_NAME "VSh v1.17 for CLI %ld"
- #define VSH_PROCESS_NAME_LEN 25
- #define VSH_PROCESS_STACK_SIZE 4096
- #define VSH_PROCESS_PRIORITY 0
-
- /* Structures */
-
- struct StartupMsg {
- struct Message sm_Message;
- struct Process *sm_CLIProcess;
- struct Window *sm_ConWindow;
- struct Device *sm_ConDevice;
- struct ConUnit *sm_ConUnit;
- BYTE *sm_LeftPath; /* path for left file requester */
- BYTE *sm_RightPath; /* path for right file requester */
- USHORT sm_Flags; /* used for HIDE flag */
- };
- /* Globals */
-
- struct ArpBase *ArpBase;
-
- /* Statics */
-
- STATIC struct ProcessControlBlock seg_pcb;
- STATIC struct StartupMsg seg_sm;
-
- STATIC BYTE process_name[VSH_PROCESS_NAME_LEN + 1],
- *vsh_segment = "l:VShSegment",
- *template = "Left,Right,HIDE/S,REMOVE/S",
- *xtra_help = "\nVSh v1.17 - Copyright © 1992 Torsten Jürgeleit\n\n"
- "Usage: VSh [Left] [Right] [REMOVE] [HIDE]\n"
- "\t[Left] = path for left file requester\n"
- "\t[Right] = path for right file requester\n"
- "\t[HIDE] = start VSh in hide mode\n"
- "\t[REMOVE] = remove VSh segment from resident list\n";
- /* Prototypes */
-
- LONG _main(BYTE *arg_line, LONG arg_len);
- BYTE *check_path(BYTE *path);
- BOOL check_valid_start(struct Process *proc, struct StartupMsg *sm);
- struct Window *get_con_window(struct Process *proc, struct StartupMsg *sm);
- LONG start_vsh_segment(struct Process *proc, struct StartupMsg *sm);
-
- /* Pragmas */
-
- #pragma regcall(_main(a0,d0))
- #pragma regcall(check_path(a0))
- #pragma regcall(check_valid_start(a0,a1))
- #pragma regcall(get_con_window(a0,a1))
- #pragma regcall(start_vsh_segment(a0,a1))
-
- /* Main - parses arguments and starts main segment */
-
- LONG
- _main(BYTE *arg_line, LONG arg_len)
- {
- LONG return_code = RETURN_FAIL;
-
- /* First open ARP library */
- if (!(ArpBase = OpenLibrary(ArpName, ArpVersion))) {
- Write(Output(), "Need arp.library v39+\n", 22L);
- } else {
- BYTE *argv[MAX_ARGUMENTS];
- USHORT i;
-
- /* Clear argument array */
- for (i = 0; i < MAX_ARGUMENTS; i++) {
- argv[i] = NULL;
- }
-
- /* Parse command line arguments */
- if (GADS(arg_line, arg_len, xtra_help, &argv[0], template) < 0) {
- Puts(argv[0]);
- } else {
-
- /* Check arguments */
- if (argv[ARGUMENT_REMOVE]) {
- LONG usage;
-
- /* Remove VSh segment from ARP resident list */
- if (usage = RemResidentPrg(vsh_segment)) {
- Printf("%s is [%ld] in use\n", vsh_segment, usage);
- } else {
- return_code = RETURN_OK;
- }
- } else {
- struct StartupMsg *sm = &seg_sm;
- BOOL error = FALSE;
-
- if (argv[ARGUMENT_HIDE]) {
-
- /* Set HIDE flag */
- sm->sm_Flags = 1;
- }
- if (argv[ARGUMENT_LEFT]) {
-
- /* Check given path for left file requester */
- if (!(sm->sm_LeftPath = check_path(argv[ARGUMENT_LEFT]))) {
- error = TRUE;
- }
- } else {
- sm->sm_LeftPath = NULL;
- }
- if (argv[ARGUMENT_RIGHT]) {
-
- /* Check given path for right file requester */
- if (!(sm->sm_RightPath = check_path(argv[ARGUMENT_RIGHT]))) {
- error = TRUE;
- }
- } else {
- sm->sm_RightPath = NULL;
- }
- if (error == FALSE) {
- struct ResidentProgramNode *rpn;
- BPTR seg;
-
- /* Check if VSh segment is already in ARP resident list */
- if (rpn = ObtainResidentPrg(vsh_segment)) {
- ReleaseResidentPrg(rpn->rpn_Segment);
- } else {
-
- /* Add VSh segment to ARP resident list */
- if (!(seg = LoadPrg(vsh_segment + 2)) &&
- !(seg = LoadPrg(vsh_segment))) {
- Printf("Can't load '%s'\n", vsh_segment);
- } else {
- if (!(rpn = AddResidentPrg(seg, vsh_segment))) {
- Printf("Can't add '%s' to ARP resident list\n",
- vsh_segment);
- UnLoadPrg(seg);
- }
- }
- }
-
- /* If VSh segment found then start it */
- if (rpn) {
- struct Process *proc = (struct Process *)FindTask(NULL);
-
- if (check_valid_start(proc, sm) == TRUE) {
- return_code = start_vsh_segment(proc, sm);
- }
- }
- }
- }
- }
- CloseLibrary(ArpBase);
- }
- return(return_code);
- }
- /* Check path for file requester */
-
- STATIC BYTE *
- check_path(BYTE *path)
- {
- struct FileInfoBlock *fib;
- BPTR lock;
- BYTE *error_msg = NULL;
-
- if (!(lock = Lock(path, (LONG)SHARED_LOCK))) {
- error_msg = "Can't lock path '%s'\n";
- } else {
- if (!(fib = AllocMem((LONG)sizeof(struct FileInfoBlock), (LONG)
- MEMF_PUBLIC))) {
- error_msg = "Out of memory\n";
- } else {
- if (Examine(lock, fib) == DOSFALSE) {
- error_msg = "Examine() failed\n";
- } else {
- if (fib->fib_DirEntryType < 0) {
- error_msg = "'%s' isn't a directory\n";
- }
- }
- FreeMem(fib, (LONG)sizeof(struct FileInfoBlock));
- }
- UnLock(lock);
- }
- if (error_msg) {
- Printf(error_msg, path);
- path = NULL;
- }
- return(path);
- }
- /* Check for a valid start of VSh */
-
- STATIC BOOL
- check_valid_start(struct Process *proc, struct StartupMsg *sm)
- {
- struct CommandLineInterface *con_cli;
- struct Window *con_win;
- BYTE *error_msg = NULL;
- BOOL success = FALSE;
-
- /* VSh startet from CLI ? */
- if (con_cli = BTOC(proc->pr_CLI)) {
-
- /* VSh started with RUN ? */
- if (con_cli->cli_Background == DOSTRUE) {
- error_msg = "Don't start VSh with RUN !";
- } else {
- struct FileHandle *con_output_fh = BTOC(proc->pr_COS);
-
- /* VSh startet from ConMan console window ? */
- if ((struct FileHandle *)con_output_fh->fh_Arg1 != con_output_fh) {
- error_msg = "Need a ConMan console window !";
- } else {
- if (!(con_win = get_con_window(proc, sm))) {
- error_msg = "Can't find console window !";
- } else {
-
- /* Check window dimension */
- if (con_win->WScreen->Width < MIN_VSH_WIDTH) {
- error_msg = "Workbench screen to small (min. 640) !";
- } else {
- struct TextFont *con_tf = con_win->RPort->Font;
-
- /* Check text font used by this CLI */
- if (con_tf->tf_XSize != 8 || con_tf->tf_YSize != 8 ||
- (con_tf->tf_Flags & FPF_PROPORTIONAL)) {
- error_msg = "Only 8x8 nonproportional fonts allowed !";
- } else {
-
- /* Check if VSh already started for this CLI */
- SPrintf(&process_name[0], VSH_PROCESS_NAME,
- proc->pr_TaskNum);
- if (FindPort(&process_name[0])) {
- error_msg = "Can't start VSh for this CLI twice !";
- } else {
- success = TRUE;
- }
- }
- }
- }
- }
- }
- if (error_msg) {
- Puts(error_msg);
- }
- }
- return(success);
- }
- /* Get pointer to the console window our process started from */
-
- STATIC struct Window *
- get_con_window(struct Process *proc, struct StartupMsg *sm)
- {
- struct Window *win = NULL;
- struct IOStdReq *req;
- struct InfoData *id;
-
- if (((struct Task *)proc)->tc_Node.ln_Type == NT_PROCESS) {
- if (id = AllocMem((LONG)sizeof(struct InfoData), (LONG)MEMF_PUBLIC)) {
- if (dos_packet((struct MsgPort *)proc->pr_ConsoleTask, (LONG)
- ACTION_DISK_INFO, CTOB(id)) == DOSTRUE) {
- win = (struct Window *)id->id_VolumeNode;
- req = (struct IOStdReq *)id->id_InUse;
- sm->sm_ConWindow = win;
- sm->sm_ConDevice = req->io_Device;
- sm->sm_ConUnit = (struct ConUnit *)req->io_Unit;
- }
- FreeMem(id, (LONG)sizeof(struct InfoData));
- }
- }
- return(win);
- }
- /* Start VSh segment */
-
- STATIC LONG
- start_vsh_segment(struct Process *proc, struct StartupMsg *sm)
- {
- struct ProcessControlBlock *pcb = &seg_pcb;
- LONG return_code = RETURN_FAIL;
-
- /* Init process control block and start VSh segment */
- pcb->pcb_StackSize = VSH_PROCESS_STACK_SIZE;
- pcb->pcb_Pri = VSH_PROCESS_PRIORITY;
- pcb->pcb_Control = PRF_NOCLI;
- if (ASyncRun(vsh_segment, NULL, pcb) < 0) {
- Printf("Can't run '%s'\n", vsh_segment);
- } else {
- struct MsgPort *mp = &proc->pr_MsgPort;
-
- /* Init startup msg and send it to VSh segment */
- sm->sm_Message.mn_ReplyPort = mp;
- sm->sm_Message.mn_Length = sizeof(struct StartupMsg);
- sm->sm_CLIProcess = proc;
- PutMsg(pcb->pcb_WBProcess, &sm->sm_Message);
-
- /* Wait for reply of startup msg */
- WaitPort(mp);
- GetMsg(mp);
- return_code = RETURN_OK;
- }
- return(return_code);
- }
-